package BeanCircularDependency;

import lombok.RequiredArgsConstructor;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
public class BeanConfig {
    @Component
    // @Scope("prototype")
    @RequiredArgsConstructor
    static class BeanA {
        @Autowired
        BeanB beanB;
        // final BeanB beanB;

        public void test() {
            System.out.println("A test");
        }
    }

    @Component
    // @Scope("prototype") // 无法解决多实例(非单例)循环依赖，每次都需要 new，无法使用缓存
    @RequiredArgsConstructor // 无法解决构造器方式注入的循环依赖，必须要有一个 Bean 不是构造器注入
    static class BeanB {
        @Autowired
        BeanA beanA;
        // final BeanA beanA;

        public void test() {
            System.out.println("B test");

            this.testx(); // 非代理对象，不会走 AOP
            ((BeanB) AopContext.currentProxy()).testx(); // exposeProxy = true
        }

        public void testx() {
            System.out.println("B testx");
        }
    }

    @Aspect
    @Component
    static class AopProxy {
        @Before("execution(* BeanConfig.BeanA.test())")
        public void beanAProxy() {
            System.out.println("BeanA AopProxy");
        }

        @Before("execution(* BeanConfig.BeanB.*())")
        public void beanBProxy() {
            System.out.println("BeanB AopProxy");
        }
    }
}
